package com.cn.xiaonuo.tcrfinance.tcrusers.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cn.xiaonuo.common.constant.Status;
import com.cn.xiaonuo.common.entity.BusinessMessage;
import com.cn.xiaonuo.common.tools.RestTemplateUtil;
import com.cn.xiaonuo.common.utils.ExportExcelUtils;
import com.cn.xiaonuo.common.utils.GetRealIPUtil;
import com.cn.xiaonuo.common.utils.payutils.GwqUtil;
import com.cn.xiaonuo.common.vo.ExcelData;
import com.cn.xiaonuo.tcrfinance.tcrusers.entity.PvGzGwj;
import com.cn.xiaonuo.tcrfinance.tcrusers.entity.PvUserEntity;
import com.cn.xiaonuo.tcrfinance.tcrusers.mapper.HpcGwjMapper;
import com.cn.xiaonuo.tcrfinance.tcrusers.param.PvUserParam;
import com.cn.xiaonuo.tcrfinance.tcrusers.param.XczxGwqBillDetailsParam;
import com.cn.xiaonuo.tcrfinance.tcrusers.service.PvHpcGwjService;
import com.cn.xiaonuo.tcrfinance.tcrusers.vo.CallGetGwqBillVo;
import com.cn.xiaonuo.tcrfinance.tcrusers.vo.GwqBalanceVo;
import com.cn.xiaonuo.tcrfinance.tcrusers.vo.GwqBillVo;
import com.cn.xiaonuo.tcrfinance.tcrusers.vo.JybGwqChangeDetailsVo;
import com.cn.xiaonuo.tcrfinance.sysmgmt.entity.PvSystemConfig;
import com.cn.xiaonuo.tcrfinance.sysmgmt.entity.SysUserHpcEntity;
import com.cn.xiaonuo.tcrfinance.sysmgmt.mapper.PvSystemConfigMapper;
import com.cn.xiaonuo.tcrfinance.sysmgmt.mapper.SysUserHpcMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class PvHpcGwjServiceImpl extends ServiceImpl<HpcGwjMapper, PvGzGwj> implements PvHpcGwjService {

    @Autowired
    private HpcGwjMapper hpcGwjMapper;
    @Autowired
    private PvSystemConfigMapper pvSystemConfigMapper;
    @Autowired
    private RestTemplateUtil restTemplateUtil;
    @Autowired
    private SysUserHpcMapper sysUserHpcMapper;

    @Override
    public BusinessMessage selectBackGwjAmounts(Map<String, Object> params) {
        BusinessMessage message = new BusinessMessage();
        try {
            Integer pageSize = Convert.toInt(params.get("pageSize"));
            Integer pageNo = Convert.toInt(params.get("pageNo"));
            if (null == pageNo || Integer.valueOf(pageNo) <= 1) {
                pageNo = 1;
            }
            if (null == pageSize || Integer.valueOf(pageSize) <= 1) {
                pageSize = 10;
            }
            PageHelper.startPage(pageNo, pageSize);
            List<Map<String, Object>> mapList = hpcGwjMapper.selectBackGwjAmounts(Convert.toStr(params.get("userId")));
            PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(mapList);
            message.setData(pageInfo);
            message.setSuccess(true);
            message.setCode("200");
            message.setMessage("操作成功");
        } catch (Exception e) {
            message.setCode("-1");
            message.setMessage("操作失败");
            message.setSuccess(false);
            e.printStackTrace();
        }
        return message;
    }

    /**
     * 资产信息
     */
    @Override
    public BusinessMessage selectBackGwjDetail(Map<String, Object> params) {
        BusinessMessage message = new BusinessMessage();
        try {
            if (StringUtils.isBlank(Convert.toStr(params.get("type")))) {
                message.setCode("-1");
                message.setMessage("参数错误");
                message.setSuccess(false);
                return message;
            }
            String begin = "2019-01-01 00:00:00";
            String end = "2100-01-01 00:00:00";
            if (null != Convert.toLong(params.get("beginTime")) || null != Convert.toLong(params.get("endTime"))) {
                ZoneId zoneId = ZoneId.systemDefault();
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                Instant instant1 = Instant.ofEpochMilli(Convert.toLong(params.get("beginTime")));
                Instant instant2 = Instant.ofEpochMilli(Convert.toLong(params.get("endTime")));
                begin = formatter.format(LocalDateTime.ofInstant(instant1, zoneId));
                end = formatter.format(LocalDateTime.ofInstant(instant2, zoneId));
            }
            Integer pageSize = Convert.toInt(params.get("pageSize"));
            Integer pageNo = Convert.toInt(params.get("pageNo"));
            if (null == pageNo || Integer.valueOf(pageNo) <= 1) {
                pageNo = 1;
            }
            if (null == pageSize || Integer.valueOf(pageSize) <= 1) {
                pageSize = 10;
            }
            PageHelper.startPage(pageNo, pageSize);
            List<Map<String, Object>> mapList = hpcGwjMapper.selectBackGwjDetail(Convert.toStr(params.get("userId")), begin, end, Convert.toStr(params.get("type")));
            PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(mapList);
            message.setData(pageInfo);
            message.setSuccess(true);
            message.setCode("200");
            message.setMessage("操作成功");
        } catch (Exception e) {
            message.setCode("-1");
            message.setMessage("操作失败");
            message.setSuccess(false);
            e.printStackTrace();
        }
        return message;
    }

    /**
     * 添加购物券
     *
     * @param params
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessMessage addGwjByFinance(Map<String, Object> params, HttpServletRequest request) {
        BusinessMessage<Object> message = new BusinessMessage<>();
        String ipAddress = GetRealIPUtil.getIpAddress(request);
        LambdaQueryWrapper<PvSystemConfig> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(PvSystemConfig::getName, "serverIp");
        PvSystemConfig config = pvSystemConfigMapper.selectOne(lambdaQueryWrapper);
        if (StringUtils.isBlank(config.getContent())) {
            message.setMessage("请优先设置访问IP");
            message.setCode("-1");
            message.setSuccess(false);
            return message;
        }
        if (config.getContent().equalsIgnoreCase(ipAddress)) {
            if (StringUtils.isBlank(Convert.toStr(params.get("phone"))) | Convert.toBigDecimal(params.get("gwjNum")).compareTo(BigDecimal.ZERO) <= 0 | StringUtils.isBlank(Convert.toStr(params.get("userId")))) {
                message.setMessage("参数错误");
                message.setCode("-1");
                message.setSuccess(false);
                return message;
            }
            LambdaQueryWrapper<SysUserHpcEntity> userWrapper = new LambdaQueryWrapper();
            userWrapper.eq(SysUserHpcEntity::getUserId, Convert.toLong(params.get("userId")));
            SysUserHpcEntity sysUser = sysUserHpcMapper.selectOne(userWrapper);
            if (null == sysUser) {
                message.setMessage("用户账号不存在");
                message.setCode("-1");
                message.setSuccess(false);
                return message;
            }
            Integer i = hpcGwjMapper.addGwj(Convert.toBigDecimal(params.get("gwjNum")), Convert.toStr(params.get("phone")));
            if (i == 1) {
                Integer integer = hpcGwjMapper.addGwjByFinance(Convert.toBigDecimal(params.get("gwjNum")), Convert.toStr(params.get("phone")), Convert.toStr(System.currentTimeMillis()),
                        "操作人ID:" + Convert.toStr(params.get("userId")) + ",ip" + ipAddress + ",原因:" + Convert.toStr(params.get("remark")));
                if (integer == 1) {
                    message.setMessage("添加成功");
                    message.setCode("200");
                    message.setSuccess(true);
                    return message;
                }
            }
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚事务
            message.setMessage("用户不存在，添加失败");
            message.setCode("-1");
            message.setSuccess(false);
            return message;
        } else {
            System.err.println("IP：" + ipAddress + "不能调用");
            message.setSuccess(false);
            message.setCode("-1");
            message.setMessage("IP：" + ipAddress + "不能调用");
            return message;
        }
    }

    /**
     * 持有商品记录
     */
    @Override
    public BusinessMessage selectAddGwjIp() {
        BusinessMessage message = new BusinessMessage();
        LambdaQueryWrapper<PvSystemConfig> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(PvSystemConfig::getName, "serverIp");
        PvSystemConfig config = pvSystemConfigMapper.selectOne(lambdaQueryWrapper);
        if (config != null) {
            message.setMessage("操作成功");
            message.setCode("200");
            message.setData(config.getContent());
            message.setSuccess(true);
            return message;
        }
        message.setMessage("操作失败");
        message.setCode("-1");
        message.setData(null);
        message.setSuccess(false);
        return message;
    }

    //新增更新购物街ip地址。
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessMessage updateAddGwjIp(Map<String, Object> params) {
        BusinessMessage message = new BusinessMessage();
        LambdaQueryWrapper<PvSystemConfig> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(PvSystemConfig::getName, "serverIp");
        PvSystemConfig config = pvSystemConfigMapper.selectOne(lambdaQueryWrapper);
        config.setContent(Convert.toStr(params.get("serverIp")));
        Integer resu = pvSystemConfigMapper.updateById(config);
        if (1 == resu) {
            message.setMessage("操作成功");
            message.setCode("200");
            message.setSuccess(true);
            return message;
        }
        message.setMessage("操作失败");
        message.setCode("-1");
        message.setSuccess(false);
        return message;
    }

    /**
     * 消费/到账记录记录
     *
     * @param pvUserParam
     * @return
     */
    @Override
    public BusinessMessage consumDetail(PvUserParam pvUserParam) {
        BusinessMessage message = new BusinessMessage();
        try {
            if (StringUtils.isBlank(Convert.toStr(pvUserParam.getType()))) {
                message.setCode("-1");
                message.setMessage("请传消费或到账的类型");
                message.setSuccess(false);
                return message;
            }
            Integer pageSize = pvUserParam.getPageSize();
            Integer pageNo = pvUserParam.getPageNo();
            if (null == pageNo || Integer.valueOf(pageNo) <= 1) {
                pageNo = 1;
            }
            if (null == pageSize || Integer.valueOf(pageSize) <= 1) {
                pageSize = 10;
            }
            PvUserEntity pvUserEntity = new PvUserEntity();
            BeanUtil.copyProperties(pvUserParam, pvUserEntity);

            PageHelper.startPage(pageNo, pageSize);
            List<Map<String, Object>> resultList = hpcGwjMapper.consumDetail(pvUserEntity);
            PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(resultList);
            Map<String, Object> resultMap = new HashMap<>();
            Double consumSummary = hpcGwjMapper.consumSum(pvUserEntity);
            if (consumSummary == null) {
                consumSummary = 0d;
            }
            resultMap.put("sumConsum", consumSummary);

            resultMap.put("pageInfo", pageInfo);
            message.setData(resultMap);
            message.setSuccess(true);
            message.setMessage(Status.success);
            message.setCode(Status.successCode);
        } catch (Exception e) {
            message.setSuccess(false);
            message.setMessage(Status.fail);
            message.setCode(Status.failCode);
            e.printStackTrace();
        }
        return message;
    }

    /**
     * 乡村振兴购物券明细
     *
     * @param param
     * @return
     */
    @Override
    public BusinessMessage xczxGwjLog(XczxGwqBillDetailsParam param) {
        BusinessMessage message = new BusinessMessage();
        try {
            if (StringUtils.isBlank(Convert.toStr(param.getPhone()))) {
                message.setCode("-1");
                message.setMessage("电话号码为空，请传入电话号码");
                message.setSuccess(false);
                return message;
            }
            JybGwqChangeDetailsVo jybGwqChangeDetailsVo = this.gwqXczxGwqBillRemoteCall(param);
            message.setData(jybGwqChangeDetailsVo);
            message.setSuccess(true);
            message.setMessage(Status.success);
            message.setCode(Status.successCode);
        } catch (Exception e) {
            message.setSuccess(false);
            message.setMessage(Status.fail);
            message.setCode(Status.failCode);
            e.printStackTrace();
        }
        return message;
    }

    public JybGwqChangeDetailsVo gwqXczxGwqBillRemoteCall(XczxGwqBillDetailsParam param) {
        String json = JSON.toJSONString(param);
        log.info("购物券交易详情远程调用入参:{}", json);
        String xczxGwqBill = restTemplateUtil.postString(GwqUtil.GWQ_URL, GwqUtil.JYB_GWQ_CHANGE_DETAILS, json, GwqUtil.TOKEN);
        log.info("购物券交易详情远程调用返回结果:{}", xczxGwqBill);
        JSONObject data = JSONObject.parseObject(xczxGwqBill);
        JSONObject jsonObject = data.getJSONObject("data");
        JybGwqChangeDetailsVo xczxGwqBillVo = jsonObject.toJavaObject(JybGwqChangeDetailsVo.class);
        return xczxGwqBillVo;
    }

    @Override
    public void xczxGwjLogExcel(XczxGwqBillDetailsParam param, HttpServletResponse response) throws Exception {
        SimpleDateFormat ymdhms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        JybGwqChangeDetailsVo detailsVo = this.gwqXczxGwqBillRemoteCall(param);
        CallGetGwqBillVo xczxGwqBillPage = detailsVo.getJybGwqBillPage();
        List<GwqBillVo> records = xczxGwqBillPage.getRecords();
        try {
            List<List<Object>> rows = new ArrayList();
            ExcelData data = new ExcelData();
            data.setName("乡村振兴购物卷收支记录导出");//sheet表名称
            //表头
            List<String> titles = new ArrayList();
            titles.add("时间");
            titles.add("类型");
            titles.add("金额");
            titles.add("有效期");
            titles.add("订单编号");
            titles.add("获赠订单运营商");

            data.setTitles(titles);
            for (GwqBillVo gwqBillVo : records) {
                List<Object> row1 = new ArrayList();
                String createdTime = ymdhms.format(gwqBillVo.getCreatedTime());
                row1.add(createdTime);
                if (gwqBillVo.getBillType().equals(0)) {
                    row1.add("冻结");
                } else if (gwqBillVo.getBillType().equals(1)) {
                    row1.add("消费");
                } else if (gwqBillVo.getBillType().equals(2)) {
                    row1.add("获赠");
                } else if (gwqBillVo.getBillType().equals(4)) {
                    row1.add("财务转入");
                } else if (gwqBillVo.getBillType().equals(5)) {
                    row1.add("过期");
                } else if (gwqBillVo.getBillType().equals(6)) {
                    row1.add("解冻");
                }else {
                    row1.add("其他");
                }
                row1.add(gwqBillVo.getAmount().doubleValue() / 100);
                if (ObjectUtils.isNotEmpty(gwqBillVo.getExpireTime())) {
                    String expireTime = ymdhms.format(gwqBillVo.getExpireTime());
                    row1.add(expireTime);
                } else {
                    row1.add("");
                }
                if (ObjectUtils.isNotEmpty(gwqBillVo.getOrderId())) {
                    row1.add(gwqBillVo.getOrderId());
                } else {
                    row1.add("");
                }

                row1.add(gwqBillVo.getShopName());
                rows.add(row1);
            }
            data.setRows(rows);
            ExportExcelUtils.exportExcel(response, "乡村振兴购物卷收支记录导出.xlsx", data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public BusinessMessage gwqBalance(XczxGwqBillDetailsParam param) {
        BusinessMessage message = new BusinessMessage();
        if (StringUtils.isBlank(Convert.toStr(param.getPhone()))) {
            message.setCode("-1");
            message.setMessage("电话号码为空，请传入电话号码");
            message.setSuccess(false);
            return message;
        }
        String json = JSON.toJSONString(param);
        log.info("购物券余额查询远程调用入参:{}", json);
        String xczxGwqBill = restTemplateUtil.postString(GwqUtil.GWQ_URL, GwqUtil.GWQ_BALANCE, json, GwqUtil.TOKEN);
        log.info("购物券余额查询远程调用返回结果:{}", xczxGwqBill);
        JSONObject data = JSONObject.parseObject(xczxGwqBill);
        JSONObject jsonObject = data.getJSONObject("data");
        GwqBalanceVo gwqBalanceVo = jsonObject.toJavaObject(GwqBalanceVo.class);
        message.setData(gwqBalanceVo);
        message.setSuccess(true);
        message.setMessage(Status.success);
        message.setCode(Status.successCode);
        return message;
    }


}
